from func import *
from guiapp import GuiApp

class MainWindow(GuiApp):
    def __init__(self, master=None):
        super().__init__(master)
        self.u_g.set(100)
        self.p_g.set(100)
        self.u_s.set(100)
        self.p_s.set(100)

        self.focal_dist.set(105)
        self.sid.set(120)
        self.ratio.set(12)
        self.center_edge_dist.set(15)
        self.misallign.set(0.1)
        self.selected_button.set(0)

        verify = self.mainwindow.register(isnum)
        verify_ = self.mainwindow.register(isnum_)
        self.Entry_ug.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_us.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_pg.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_ps.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_theta.configure(validate="key", validatecommand=(verify_, '%P'))
        self.Entry_f0.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_sid.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_r.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_c.configure(validate="key", validatecommand=(verify, '%P'))
        self.Entry_z.configure(validate="key", validatecommand=(verify_, '%P'))
        
        self.Entry_ug.bind('<Return>', self.__grid_pitch_update)
        self.Entry_ug.bind('<FocusOut>', self.__grid_pitch_update)
        self.Entry_pg.bind('<Return>', self.__grid_density_update)
        self.Entry_pg.bind('<FocusOut>', self.__grid_density_update)
        self.Entry_us.bind('<Return>', self.__pixel_size_updata)
        self.Entry_us.bind('<FocusOut>', self.__pixel_size_updata)
        self.Entry_ps.bind('<Return>', self.__sampling_freq_update)
        self.Entry_ps.bind('<FocusOut>', self.__sampling_freq_update)

        self.Button_calculate_moire.configure(command=self.__calculate_moire)
        self.Button_calculate_sid.configure(command=self.__calculate_sid)
        self.Radiobutton_dr.configure(command=self.__calculate_sid)
        self.Radiobutton_mammo.configure(command=self.__calculate_sid)
        self.Button_exit.configure(command=self.__exit_callback)

        self.Entry_ug.bind_all('<Return>', self.__calculate_moire, add='+')
        self.Entry_ug.bind_all('<FocusOut>',self. __calculate_moire, add='+')
        self.Entry_f0.bind_all('<Return>', self.__calculate_sid, add='+')
        self.Entry_f0.bind_all('<FocusOut>', self.__calculate_sid, add='+')
        
    def __calculate_moire(self, *args):
        u_g = self.u_g.get()
        u_s = self.u_s.get()
        theta = self.theta.get() * math.pi / 180
        u_m = moire_freq(u_g, u_s, theta)
        if u_m:
            p_m = 1/u_m
        else:
            p_m = math.inf
        self.u_m.set(round(u_m, 2))
        self.p_m.set(round(p_m, 2))
    
    def __calculate_sid(self, *args):
        f0 = self.focal_dist.get()
        r = self.ratio.get()
        c = self.center_edge_dist.get()
        z = self.misallign.get()
        sid = self.sid.get()
        vdict = {0: 0.4,
                 1: 0.2}
        V = vdict[self.selected_button.get()]
        al, ar = Attenuation(f0, sid, c, r, z)
        mi, ma = SID_Range(f0, c, r, V, z)
        self.cutoff_left.set(round(al * 100, 2))
        self.cutoff_right.set(round(ar * 100, 2))
        self.sid_min.set(round(mi, 2))
        self.sid_max.set(round(ma, 2))
    
    def __exit_callback(self, *args):
        self.mainwindow.destroy()
    
    def __grid_pitch_update(self, *args):
        self.p_g.set(round(10000/self.u_g.get(), 2))
    
    def __grid_density_update(self, *args):
        self.u_g.set(round(10000/self.p_g.get(), 2))
    
    def __pixel_size_updata(self, *args):
        self.p_s.set(round(10000/self.u_s.get(), 2))
    
    def __sampling_freq_update(self, *args):
        self.u_s.set(round(10000/self.p_s.get(), 2))

if __name__ == '__main__':
    app = MainWindow()
    app.run()